/* 使用实例：
*  1.初始化地图
    var map = new window.openlayersMap({
        centerPoint: [118.804783999999993, 34.111022],
    });
    map.init('orthMap', {
        jdlayers: 'http://10.38.16.21:6080/arcgis/rest/services/sldt/MapServer/WMTS',
        yxlayers: 'http://10.38.16.21:6080/arcgis/rest/services/yxdt/MapServer/WMTS'
    }, 'http://10.38.16.21:6080/arcgis/rest/services/yxzj/MapServer/WMTS')
*  2.切换瓦片地图
    map.changeLayers('jdlayers');
*  3.重新设置地图中心位置
    map.resetCenter(118.804783999999993, 34.111022);
*  4.清除所有点位、线段、圆等元素
    map.removerAll();
*  5.画圆
    map.addCircular({centreJd: '118.75764727592468', centreWd: '34.12535905838013',
        list:[
            {"id":"4e08fb201ba04b03bd066524da694006","range":"300","color":"rgba(255, 0, 0, 0.4)"},
            {"id":"03145f89160d42a98bd0c94ad9ad49e4","range":"400","color":"rgba(231, 161, 79, 0.4)"},
            {"id":"cd13f9be03b24f3ca89895e16cfe5d54","range":"500","color":"rgba(52, 168, 83, 0.4)"}
        ]
    });
*  6.画点
    map.onPint({
        point: { // 打点
            list: [
                {lonlat: [118.79136800765991, 34.11171197891235], id: '111',
                    img: '/static/icon/levels/internetBar_blue.png',
                    TitleList: '<div>点位详情1</div>'},
                {lonlat: [118.79050970077515, 34.10561800003052], id: '222',
                    img: '/static/icon/levels/internetBar_blue.png',
                    TitleList: '<div>点位详情2</div>'},
                {lonlat: [118.79681825637817, 34.101154804229736], id: '333',
                    img: '/static/icon/levels/internetBar_blue.png',
                    TitleList: '<div>点位详情3</div>'},
            ],
            number: true, // 序号
            click: { // 点击出现弹窗
                target: 'mapView',
            },
         },
         line: { // 划线
            arrow: true, // 方向
            arrowImg: '/static/icon/point_1.png', // 可缺
         }
    });
*  7.点位高亮
    map.onHighLight({
        lonlat: [118.79136800765991, 34.11171197891235], id: '111',
            img: '/static/icon/levels/internetBar_blue.png'
        });
* */
(function() {
    var ol = window.ol;
    function OpenlayersMap() {};
    OpenlayersMap.prototype = {
        _data: {},
        _layers: [],
        _layersAdd: [],
        _overlayAdd: [],
        _layer: new ol.layer.Vector({
            source: new ol.source.Vector()
        }),
        _initLayers: function(url, visible) {
            var resolutions = this._data.resolutions, origin = this._data.origin,
                matrixIds = this._data.matrixIds,
                params = {
                    source: new ol.source.WMTS({
                        url: url,
                        tileGrid: new ol.tilegrid.WMTS({origin, resolutions, matrixIds}),
                    })
                };
            if (typeof visible === 'boolean') params.visible = visible;
            return new ol.layer.Tile(params);
        },
        _initMap: function(target, arr) {
            this._data.targetDom = target;
            this.dsMap = new ol.Map({
                target: target,
                layers: arr,
                projection: 'EPSG:4326',
                view: new ol.View({
                    center: this._data.centerPoint,
                    minZoom: 12,
                    maxZoom: 20,
                    projection: 'EPSG:4326',
                    zoom: 15
                })
            });
        },
        initMap: function (target, layersUrl, titleUrl) {
            this._layers = [];
            var arrs = Object.getOwnPropertyNames(layersUrl), _this = this, layers = [];
            arrs.forEach(function (item, index) {
                var visible = false;
                if (index === 0) visible = true;
                _this[item] = _this._initLayers(layersUrl[item], visible);
                layers.push(_this[item]);
                _this._layers.push(item)
            });
            if (titleUrl) {
                var Tile = this._initLayers(titleUrl);
                layers.push(Tile);
            }
            layers.push(this._layer)
            this._initMap(target, layers);
        },
        init: function (obj) {
            this._data = {
                centerPoint: obj.centerPoint || [118.804783999999993, 34.111022],
                resolutions: obj.resolutions || [1.406250026231578, 0.703125013115789, 0.3515625065578945, 0.17578125327894775, 0.08789062663947399, 0.043945313319736994, 0.021972656659868472, 0.010986328329934226, 0.005493164164967124, 0.0027465820824835504, 0.0013732910412417797, 6.866455206208899E-4, 3.433227603104438E-4, 1.716613801552224E-4, 8.583069007761132E-5, 4.291534503880566E-5, 2.1457672519402802E-5, 1.0728836259701401E-5, 5.364418129850712E-6, 2.682209064925356E-6, 1.341104532462678E-6],
                origin: obj.origin || [-180.0, 90.0],
                matrixIds: obj.matrixIds || ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20']
            };
            var layers = {}, showLayer = '';
            obj.bgLagers.forEach(function (item) {
                layers[item.key] = item.url;
                if (item.default) showLayer = item.key;
            })
            this.initMap(obj.domID, layers, obj.bgStreet)
            this.changeLayers(showLayer);
        },
        changeLayers: function (str) {
            var flag = false, _this = this;
            this._layers.forEach(function (item, index) {
                if (item === str) {
                    _this[item].setVisible(true);
                    flag = true;
                } else _this[item].setVisible(false);
            })
            if (!flag) this[this._layers[0]].setVisible(true);
        },
        resetCenter: function (log, lat) {
            this.dsMap.getView().setCenter([Number(log), Number(lat)]);
        },
        onPint: function (obj) {
            var newPoints = [], _this = this;
            if (obj.point) {
                var point = {
                    list: obj.point.list || [],
                    number: obj.point.number || false,
                    click: obj.point.click || false,
                };
                point.list.forEach(function (item, index) {
                    newPoints.push(item.lonlat);
                    _this._addMarkerToMap(item);
                    if (point.number) _this._crateOverlay(item, index);
                });
                if (point.click) this._addClick(point.click, point.list);
            }
            if (obj.line) {
                var line = {
                    arrow: obj.line.arrow || false,
                    arrowImg: obj.line.arrowImg || ''
                }, source = new ol.source.Vector(),
                    feature = new ol.Feature({
                        geometry: new ol.geom.LineString(newPoints)
                    });
                source.addFeature(feature);
                var vectorLayer = new ol.layer.Vector({
                    source: source,
                    style: this._styleFunction(feature, {
                        arrow: line.arrow,
                        arrowImg: line.arrowImg
                    }),
                });
                var layersArray = this.dsMap.getLayers();
                layersArray.insertAt(3, vectorLayer);
                this._layersAdd.push(vectorLayer)
            }
        },
        _addClick: function (obj, dataList) {
            var mapView = document.getElementById(obj.target), self = this;
            mapView.innerHTML = '<div id="popup" class="ol-popup" >' +
                '<a href="#" id="popup-closer" class="ol-popup-closer"></a>' +
                '<div id="popup-content" style="color:#fff;font-size:14px"></div>' +
                '</div>';
            var container = document.getElementById('popup'),
                content = document.getElementById('popup-content'),
                popupCloser = document.getElementById('popup-closer');
            var overlay = new ol.Overlay(({
                element: container,
                autoPan: true,
                autoPanAnimation: {
                    duration: 250
                }
            }));
            if (popupCloser) {
                popupCloser.addEventListener('click', () => {
                    container.style.display = 'none';
                    overlay.setPosition(undefined);
                    popupCloser.blur();
                    return false;
                })
            }
            this.clickMapEvent = this.dsMap.on('click', function (e) {
                if (container) {
                    container.style.display = 'block';
                }
                var pixel = self.dsMap.getEventPixel(e.originalEvent);
                self.dsMap.forEachFeatureAtPixel(pixel, function (feature) {
                    var coordinate = e.coordinate;
                    var point = dataList.filter(function (item) {return item.id === feature.id_})
                    if (point[0]) {
                        var TitleList = point[0].TitleList;
                        content.innerHTML = TitleList;
                        overlay.setPosition(coordinate);
                        self.dsMap.addOverlay(overlay);
                        self._overlayAdd.push(overlay);
                    }
                })
            })
        },
        _addMarkerToMap: function (obj) {
            var iconFeature = new ol.Feature({
                geometry: new ol.geom.Point(obj.lonlat),
                marker: obj,
                zIndex: 20,
            });
            iconFeature.setStyle(new ol.style.Style({
                image: new ol.style.Icon({
                    src: obj.img,
                    img: undefined, imgSize: undefined,
                    anchor: [0.5, 0.95]
                })
            }));
            iconFeature.setId(obj.id);
            this._layer.getSource().addFeature(iconFeature);
        },
        _crateOverlay: function (obj, index) {
            var div = document.createElement('div');
            div.className = 'circular';
            div.innerHTML = index + 1;
            div.style.cssText = 'background-color:#234dbc;width:20px;height:20px;line-height:20px;border-radius:10px;text-align:center;color:#fff;font-size:12px;';
            var overlay = new ol.Overlay({
                element: div,
                autoPan: false,
                offset:[-30,-60]
            });
            this._overlayAdd.push(overlay);
            this.dsMap.addOverlay(overlay);
            overlay.setPosition(obj.lonlat);
        },
        _styleFunction: function (feature, arrowParams) {
            var geometry = feature.getGeometry(),
                styles = [
                    new ol.style.Style({
                        fill: new ol.style.Style({
                            color: 'rgba(255, 255, 255, 0.2)'
                        }),
                        stroke: new ol.style.Stroke({
                            color: '#f00',
                            width: 4
                        }),
                        image: new ol.style.Circle({
                            radius: 2,
                            fill: new ol.style.Fill({
                                color: '#f00'
                            })
                        })
                    })
                ];
            if (arrowParams.arrow)
                geometry.forEachSegment(function (start, end) {
                    var dx = end[0] - start[0]
                    var dy = end[1] - start[1]
                    var rotation = Math.atan2(dy, dx)
                    styles.push(new ol.style.Style({
                        geometry: new ol.geom.Point(end),
                        image: new ol.style.Icon({
                            src: arrowParams.arrowImg,
                            anchor: [0.75, 0.5],
                            rotateWithView: false,
                            rotation: -rotation
                        })
                    }))
                });
            return styles;
        },
        _compare: function (obj1, obj2) {
            if (obj1.range > obj2.range) {
                return -1;
            } else {
                return 1;
            }
        },
        _addCircular: function (obj) {
            this.resetCenter(obj.centreJd, obj.centreWd)
            var yxfws = [];
            obj.list.forEach(function (item) {
                yxfws.push(item.range);
            });
            var arr = JSON.parse(JSON.stringify(obj.list)), seqs = arr.sort(this._compare),
                lonlat = [parseFloat(obj.centreJd), parseFloat(obj.centreWd)],
                features = new ol.Collection();
            seqs.forEach(function (seq) {
                var center = lonlat, radius = (seq.range && Number(seq.range)) || 0,
                    options = {step: 64, units: 'meters', properties: {foo: 'bar'}},
                    cirlceData = window.turf.circle(center, radius, options),
                    circleFeature = new ol.format.GeoJSON().readFeatures(cirlceData);
                circleFeature[0].setId(seq.id);
                features.push(circleFeature[0]);
            });
            var circleLayer = new ol.layer.Vector({
                source: new ol.source.Vector({features: features}),
                style: function (feature) {
                    var findObj = seqs.filter(function (item) {return item.id == feature.id_});
                    var s = new ol.style.Style({
                        fill: new ol.style.Fill({
                            color: findObj[0].color || 'rgba(255, 0, 0, 0.4)'
                        }),
                        stroke: new ol.style.Stroke({
                            color: '#ffcc33',
                            width: 2
                        })
                    })
                    return s;
                }
            })
            this.dsMap.addLayer(circleLayer);
            this._layersAdd.push(circleLayer);
        },
        addCircular: function (obj) {
            if (window.turf) {
                this._addCircular(obj)
            } else console.error('请安装插件')
        },
        removerAll: function () {
            var _this = this;
            if (this.clickMapEvent) {
                window.ol.Observable.unByKey(this.clickMapEvent);
            }
            if (this._layer) {
                var feature = this._layer.getSource().getFeatures();
                if (feature.length > 0) {
                    feature.forEach(function (item) {
                        _this._layer.getSource().removeFeature(item);
                    })
                }
            }
            if (this._layersAdd.length > 0) {
                this._layersAdd.forEach(function (item) {
                    _this.dsMap.removeLayer(item);
                });
                this._layersAdd = [];
            }
            if (this._overlayAdd.length > 0) {
                this._overlayAdd.map(function (item) {
                    _this.dsMap.removeOverlay(item);
                });
                this._overlayAdd = [];
            }
        },
        onHighLight: function (obj, item) {
            if (obj.lonlat && obj.lonlat[1]) {
                var featureSelectStyle, selectedByAttriFeature,
                    feature = this._layer.getSource().getFeatures();
                for (var i = 0; i < feature.length; i++) {
                    var mapId = feature[i].id_, num = mapId.indexOf('_'),
                        checkedID = mapId.slice(num + 1, mapId.length);
                    if (checkedID === obj.id) {
                        selectedByAttriFeature = feature[i];
                        break;
                    }
                }
                if (selectedByAttriFeature) {
                    this.resetCenter(obj.lonlat[0], obj.lonlat[1]);
                    this.dsMap.getView().setZoom(15);
                    var _this = this, timer = setInterval(function () {
                        featureSelectStyle = new ol.style.Style({
                            image: new ol.style.Icon({
                                src: obj.img,
                                scale: 1,
                                offset: [-38, -50],
                                offsetOrigin: 'bottom-right',
                                size: [110, 110],
                                color: '#ff0e05'
                            }),
                            zIndex: 200,
                        })
                        selectedByAttriFeature.setStyle(featureSelectStyle)
                        setTimeout(function () {
                            _this.clearHighLight(featureSelectStyle, selectedByAttriFeature, obj)
                        }, 400)
                    }, 600)
                    setTimeout(function () {
                        clearInterval(timer);
                    }, 5500)
                } else console.error('暂无点位数据，请先打点！');
            } else console.error('暂无点位数据！');
        },
        clearHighLight: function (featureSelectStyle, selectedByAttriFeature, item) {
            featureSelectStyle = new ol.style.Style({
                image: new ol.style.Icon({
                    src: item.img,
                    scale: 1,
                    offset: [-38, -50],
                    offsetOrigin: 'bottom-right',
                    size: [110, 110],
                }),
                zIndex: 199,
            });
            selectedByAttriFeature.setStyle(featureSelectStyle);
        },
    }
    window.openlayersMap = new OpenlayersMap();
}())